package com.deters.oauth2.config;

import com.deters.oauth2.domain.CustomUserDetail;
import com.deters.oauth2.entity.User;
import com.deters.oauth2.repository.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * Security核心配置
 *
 * @author ZhuLQ
 * @date 2020/11/25
 * @description 这里security主要承担的角色是，用户资源管理，简单地说就是，
 * 在客户端发送登录请求的时候，security会将先去根据用户输入的用户名和密码，去查数据库，如果匹配，那么就把相应的用户信息进行一层转换，
 * 然后交给认证授权管理器，然后认证授权管理器会根据相应的用户，给他分发一个token(令牌)，然后下次进行请求的时候，携带着该token(令牌)，
 * 认证授权管理器就能根据该token(令牌)去找到相应的用户了。
 */
@Configuration
@EnableWebSecurity
@Slf4j
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserRepository userRepository;

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        return new UserDetailsService(){
            @Override
            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                log.info("username:{}",username);
                User user = userRepository.findUserByAccount(username);
                if(user != null){
                    CustomUserDetail customUserDetail = new CustomUserDetail();
                    customUserDetail.setUsername(user.getAccount());
                    customUserDetail.setPassword("{bcrypt}"+bCryptPasswordEncoder.encode(user.getPassword()));
                    List<GrantedAuthority> list = AuthorityUtils.createAuthorityList(user.getRole().getRole());
                    customUserDetail.setAuthorities(list);
                    return customUserDetail;
                }else {//返回空
                    return null;
                }

            }
        };
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }
}